package com.gzhryc.shared_device.oem.micro.api.controllers.xcx.v1.bxscn;

import java.text.ParseException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.time.DateUtils;

import com.gzhryc.common.IDTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.bxscn.code.BXSCNCostConfig;
import com.gzhryc.shared_device.bxscn.code.dao.db.BXSCNFeeTemplate;
import com.gzhryc.shared_device.bxscn.code.dao.db.BXSCNOrder;
import com.gzhryc.shared_device.bxscn.code.dao.db.PortableEnergyCabinet;
import com.gzhryc.shared_device.bxscn.code.dao.enums.BXSCNOrderEnum;
import com.gzhryc.shared_device.bxscn.code.dao.enums.PortableEnergyCabinetEnum;
import com.gzhryc.shared_device.bxscn.code.services.BXSCNFeeTemplateService;
import com.gzhryc.shared_device.bxscn.code.services.BXSCNOrderService;
import com.gzhryc.shared_device.bxscn.code.services.PortableEnergyCabinetService;
import com.gzhryc.shared_device.bxscn.code.services.models.BXSCNOpenSlotCacheData;
import com.gzhryc.shared_device.bxscn.core.IBXSCNNetworkService;
import com.gzhryc.shared_device.bxscn.core.models.BXSCNExecuteResult;
import com.gzhryc.shared_device.bxscn.core.models.BXSCNOpenSlotCommand;
import com.gzhryc.shared_device.common.device.dao.db.Device;
import com.gzhryc.shared_device.common.device.services.DeviceService;
import com.gzhryc.shared_device.oem.code.ConfigUtils;
import com.gzhryc.shared_device.oem.code.HttpNetworkServiceUtils;
import com.gzhryc.shared_device.oem.code.config.dao.enums.EAgreementCode;
import com.gzhryc.shared_device.oem.code.device.BXSCNCacheManager;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.member.LoginMember;
import com.gzhryc.shared_device.oem.code.member.dao.db.MemberAgreement;
import com.gzhryc.shared_device.oem.code.member.dao.enums.MemberAgreementEnum;
import com.gzhryc.shared_device.oem.code.member.services.MemberAgreementService;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlaceBusinessConfig;
import com.gzhryc.shared_device.oem.code.place.services.PlaceBusinessConfigService;
import com.gzhryc.shared_device.oem.micro.api.MicroConstants;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.ClientAPICodeConstants;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNOpenSlotRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNOpenSlotResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNOpenSlotResultRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNOpenSlotResultResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNScanGetRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNScanGetResponse;

public class BXSCNScanController {

    static Logger log = Logger.getLogger(BXSCNScanController.class);

    @Route(value = { "/xcx/v1/bxscn/scan/get.do" }, method = "POST")
    public BXSCNScanGetResponse getSharedDevice(HttpServletRequest request) {
        BXSCNScanGetResponse apiResp = new BXSCNScanGetResponse(ClientAPICodeConstants.NULL_DATA, "未找到设备信息");
        BXSCNScanGetRequest apiReq = WebUtils.getJsonRequest(request, BXSCNScanGetRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn())) {
            String deviceSn = apiReq.getBody().getDeviceSn().trim();
            Device device = DeviceService.self().getByDeviceSn(deviceSn);
            if (device == null || device.getPlaceId() == null) {
                log.error("未找到{{0}}设备或未部署",deviceSn);
                return apiResp;
            }

            PortableEnergyCabinet portableEnergyCabinet = PortableEnergyCabinetService.self().getByDeviceSn(deviceSn);
            if (portableEnergyCabinet == null) {
                log.error("未找到{{0}}设备",deviceSn);
                return apiResp;
            }

            apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
            apiResp.getBody().setDeviceSn(device.getDeviceSn());
            apiResp.getBody().setPlaceName(device.getPlaceName());
            apiResp.getBody().setPlaceAreaName(device.getAreaName());
            if(PortableEnergyCabinetEnum.State.Online.index().equals(portableEnergyCabinet.getState())) {
                //TODO 检查充电饱和状态
                apiResp.getBody().setState(1);  //在线
            }else{
                apiResp.getBody().setState(2);  //离线
            }

            BXSCNFeeTemplate feeTemplate = null;
            PlaceBusinessConfig deviceFunc = PlaceBusinessConfigService.self().getByKeys(device.getPlaceId(), EDeviceFunCode.BXSCN.index());
            if(deviceFunc != null && deviceFunc.getFeeTemplateId() != null) {
                feeTemplate = BXSCNFeeTemplateService.self().getById(deviceFunc.getFeeTemplateId());
            }

            if(feeTemplate == null){
                BXSCNCostConfig costConfig = ConfigUtils.getBXSCNCostConfig();
                feeTemplate = BXSCNFeeTemplateService.buildByDefault(costConfig);
            }

            apiResp.getBody().setDepositMoneyStr(feeTemplate.getDepositMoneyStr());
            apiResp.getBody().setDayMaxMoneyStr(feeTemplate.getDayMaxMoneyStr());
            apiResp.getBody().setPayIntervalMoneyStr(feeTemplate.getPayIntervalMoneyStr());
            apiResp.getBody().setFreeTimes(feeTemplate.getFreeTimes());
            
            //检查协议
            LoginMember loginMember = WebUtils.getAttribute(request, MicroConstants.ATTR_LOGIN_MEMBER, LoginMember.class);
            if(loginMember != null && StringTools.isNotBlank(apiReq.getBody().getAppId())) {
	            MemberAgreement memberAgreement = MemberAgreementService.self().getByKeys(loginMember.getId(), EAgreementCode.RentAgreement.name()
	            		, apiReq.getBody().getAppId());
	            if(memberAgreement != null && MemberAgreementEnum.State.Signing.index().equals(memberAgreement.getState())) {
	            	apiResp.getBody().setSigningAgreement(true);
	            }
            }

        }
        return apiResp;
    }

    @Route(value = { "/xcx/v1/bxscn/slot/open.do" }, method = "POST")
    public BXSCNOpenSlotResponse openSlot(HttpServletRequest request){
        BXSCNOpenSlotResponse apiResp = new BXSCNOpenSlotResponse(ClientAPICodeConstants.NULL_DATA, "未找到设备信息");
        BXSCNOpenSlotRequest apiReq = WebUtils.getJsonRequest(request, BXSCNOpenSlotRequest.class);
        LoginMember member = WebUtils.getAttribute(request, MicroConstants.ATTR_LOGIN_MEMBER, LoginMember.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn()) && member != null) {
            String deviceSn = apiReq.getBody().getDeviceSn().trim();
            PortableEnergyCabinet portableEnergyCabinet = PortableEnergyCabinetService.self().getByDeviceSn(deviceSn);
            if (portableEnergyCabinet == null) {
                log.error("未找到{{0}}设备",deviceSn);
                return apiResp;
            }

            Date currentDate = new Date();
            if(StringTools.isNotBlank(apiReq.getBody().getCreateDate())){
                try {
                    currentDate = DateUtils.parseDate(apiReq.getBody().getCreateDate(),"yyy-MM-dd HH:mm:ss","yyy-MM-dd");
                } catch (ParseException e) {
                    log.error(e.getMessage(),e);
                }
            }
            BXSCNOrder deviceOrder = null;
            if(StringTools.isNotBlank(apiReq.getBody().getTradeNo())){
                deviceOrder = BXSCNOrderService.self(currentDate).getByTradeNo(apiReq.getBody().getTradeNo());
            }

            if(deviceOrder == null){
                //未找到设备，查询会员是否有待归还的设备
                deviceOrder = BXSCNOrderService.self(currentDate).getNewsByMemberIdAndState(member.getId(), BXSCNOrderEnum.State.Lease.index());
            }

            if(deviceOrder == null){
                apiResp.setCode(ClientAPICodeConstants.EXECUTE_ERROR,"请确定有订单需要归还或已获得代归还授权");
                return apiResp;
            }

            IBXSCNNetworkService networkService = HttpNetworkServiceUtils.getBXSCNNetworkService(portableEnergyCabinet.getIotNodeId());
            if(networkService != null){
                //设置缓存
                BXSCNOpenSlotCacheData openSlotCacheData = new BXSCNOpenSlotCacheData();
                openSlotCacheData.setMemberId(member.getId());
                if(deviceOrder != null) {
                    openSlotCacheData.setTradeNo(deviceOrder.getTradeNo());
                }
                String messageId = IDTools.getTimestampSecondID();
                BXSCNCacheManager.self().setCommandResult(portableEnergyCabinet.getDeviceSn(),messageId, JsonTools.toJson(openSlotCacheData));

                log.info("开仓缓存：{{0}}，{{1}}",portableEnergyCabinet.getDeviceSn(),messageId);

                BXSCNOpenSlotCommand returnCommand = new BXSCNOpenSlotCommand();
                returnCommand.setDeviceSn(portableEnergyCabinet.getDeviceSn());
                returnCommand.setMessageId(messageId);
                BXSCNExecuteResult executeResult = networkService.openSlot(returnCommand);
                if(BXSCNExecuteResult.SUCCESS.equals(executeResult.getCode())){
                    apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                    apiResp.getBody().setMessageId(executeResult.getMessageId());
                }else{
                    apiResp.setCode(ClientAPICodeConstants.EXECUTE_ERROR,"开仓失败，请稍后再试或联系客服");
                }
            }else{
                log.error("未获取{{0}}的IOT服务",portableEnergyCabinet.getIotNodeId());
            }

        }
        return apiResp;
    }

    @Route(value = { "/xcx/v1/bxscn/slot/open/result.do" }, method = "POST")
    public BXSCNOpenSlotResultResponse openSlotResult(HttpServletRequest request){
        BXSCNOpenSlotResultResponse apiResp = new BXSCNOpenSlotResultResponse(ClientAPICodeConstants.NULL_DATA,"未找到结果");
        BXSCNOpenSlotResultRequest apiReq = WebUtils.getJsonRequest(request, BXSCNOpenSlotResultRequest.class);
        log.info("开仓结果请求：{{0:json}}",apiReq);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn()) && StringTools.isNotBlank(apiReq.getBody().getMessageId())) {
            BXSCNOpenSlotCacheData openSlotCacheData = BXSCNCacheManager.self().getCommandResult(apiReq.getBody().getDeviceSn()
                    ,apiReq.getBody().getMessageId(),BXSCNOpenSlotCacheData.class);
            if(openSlotCacheData != null){
                if(openSlotCacheData.getOpenSlotResult() != null) {
                    apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                    apiResp.getBody().setSlotNum(openSlotCacheData.getOpenSlotResult().getSlotNum());
                    apiResp.getBody().setResultCode(openSlotCacheData.getOpenSlotResult().getResultCode());
                }else{
                    apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                    apiResp.getBody().setResultCode(0);
                }
            }
        }
        return apiResp;
    }
}
